package com.higgins.law.server;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Files.Copy;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

public class GoogleDrive {
	  private static String CLIENT_ID = "729057867694.apps.googleusercontent.com";
	  private static String CLIENT_SECRET = "Udxg4bOCEoWcvl96oK-JEGmB";
	  private static String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";

	public Drive authenticate()	throws Exception	{
	    HttpTransport httpTransport = new NetHttpTransport();
	    JsonFactory jsonFactory = new JacksonFactory();
	   
	    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
	        httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, Arrays.asList(DriveScopes.DRIVE))
	        .setAccessType("online")
	        .setApprovalPrompt("auto").build();
	    
	    String url = flow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI).build();
	    System.out.println("Please open the following URL in your browser then type the authorization code:");
	    System.out.println("  " + url);
	    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	    String code = br.readLine(); // authorisation code
	    
	    GoogleTokenResponse response = flow.newTokenRequest(code).setRedirectUri(REDIRECT_URI).execute();
	    GoogleCredential credential = new GoogleCredential().setFromTokenResponse(response);
	    
	    //Create a new authorized API client
	    Drive service = new Drive.Builder(httpTransport, jsonFactory, credential).build();

	    return service;
	}

	public File getFile(Drive drive, String filename)	{
		@SuppressWarnings("unused")
		String fileId = null;
		File myFile = null;
		List<File> myList;
		try {
			myList = retrieveAllFiles(drive);
			for (File tempFile:myList)	{
				System.out.println(tempFile.getId() + "; " + tempFile.getTitle() + "; " + tempFile.getDownloadUrl());
				if ((tempFile.getTitle().equals(filename)))
					myFile = tempFile;
			}		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println(e.toString());
		}
		return myFile;
	}
	
	public String generateDuplicateFileName(String newFileTitle, String titlePartII)	{
		int endOfFileName = newFileTitle.length()-4;
		String newTitle = newFileTitle.substring(0, endOfFileName);
		String fileExt = newFileTitle.substring(endOfFileName);			
		newFileTitle = newTitle + " - " + titlePartII + fileExt;
		return newFileTitle;
	}
	
	public String insertFile(Drive service)	{
		String fileId = null;
	    //Insert a file  
	    File body = new File();
	    body.setTitle("My document");
	    body.setDescription("A test document");
	    body.setMimeType("text/plain");
	    
	    java.io.File fileContent = new java.io.File("/document.txt");
	    FileContent mediaContent = new FileContent("text/plain", fileContent);

	    File file;
		try {
			file = service.files().insert(body, mediaContent).execute();
			fileId = file.getId();
		    System.out.println("File ID: " + file.getId());				
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return fileId;
	}
	
	public void printFile(Drive service, String fileId) {

	    try {
	      File file = service.files().get(fileId).execute();

	      System.out.println("Title: " + file.getTitle());
	      System.out.println("Description: " + file.getDescription());
	      System.out.println("MIME type: " + file.getMimeType());
	    } catch (IOException e) {
	      System.out.println("An error occured: " + e);
	    }
	  }

	  /**
	   * Download a file's content.
	   * 
	   * @param service Drive API service instance.
	   * @param file Drive File instance.
	   * @return InputStream containing the file's content if successful,
	   *         {@code null} otherwise.
	   */
	  public InputStream downloadFile(Drive service, File file) {
		try {
//			File file = service.files().get(fileId).execute();
		    if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
		        HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
		        return resp.getContent();
		    }
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return null;
	  }

	  public List<File> retrieveAllFiles(Drive service) throws Exception	{
		    List<File> result = new ArrayList<File>();
		    Files.List request = service.files().list();

		    do {
		      try {
		        FileList files = request.execute();

		        result.addAll(files.getItems());
		        request.setPageToken(files.getNextPageToken());
		      } catch (IOException e) {
		        System.out.println("An error occurred: " + e);
		        request.setPageToken(null);
		      }
		    } while (request.getPageToken() != null &&
		             request.getPageToken().length() > 0);

		    return result;
		  }	  
	  
	  public static File copyFile(Drive service, String originFileId, String copyTitle) {
		    File copiedFile = new File();
		    copiedFile.setTitle(copyTitle);
//		    copiedFile.setEditable(false);
//		    copiedFile.setMimeType(type);
		    
		    try {
		    	Copy myCopy = service.files().copy(originFileId, copiedFile);
		    	myCopy = myCopy.setConvert(false);
		      return myCopy.execute();
		    } catch (IOException e) {
		      System.out.println("An error occurred: " + e);
		    }
		    return null;
		  }
	  
	  public static InputStream downloadWordFile(Drive service, File file) {
	      java.io.File f = null;
	      InputStream inputStream = null;
		    try {
//		      File file = service.files().get(fileId).execute();

		      if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
				  HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
			      inputStream = resp.getContent();
			      
			      /*
			      f=new java.io.File("outFile.rtf");
			      
			      // REPLACE THIS WITH A PROPER WORD DOC READER
			      
			      OutputStream out=new FileOutputStream(f);
			      byte buf[]=new byte[1024];
			      int len;
			      while((len=inputStream.read(buf))>0)	{
			    	  String localLine = buf.toString();
			    	  String newString = localLine;
			    	  
			    	  String searchString = "{Lawfirm}";
			    	  if (localLine.contains(searchString))	{
			    		  int start = localLine.indexOf(searchString);
			    		  int end = start + searchString.length();
			    		  newString = localLine.substring(0, start) + 
			    		  			"MY LAW FIRM" + localLine.substring(end);
			    	  }
			    	  
			    	  buf = newString.getBytes("UTF-16LE");
				      out.write(buf,0,len);
			      }
			      out.close();
			      inputStream.close();
			      */
			  }
		    } catch (IOException e) {
			      System.out.println("An error occurred: " + e);
		    }
	      return inputStream;
	  }	  
		      
		      
	  public static File updateFile(Drive service, File file, java.io.File f) {
		    try {
		      FileContent mediaContent = new FileContent(file.getMimeType(), f);

		      // Send the request to the API.
		      File updatedFile = service.files().update(file.getId(), file, mediaContent).execute();

		      return updatedFile;
		    } catch (IOException e) {
		      System.out.println("An error occurred: " + e);
		      return null;
		    }
		  }	  
	/*
	  public void blobStore()	{
		// Get a file service
		  FileService fileService = FileServiceFactory.getFileService();
	
		  // Create a new Blob file with mime-type "text/plain"
		  AppEngineFile file = fileService.createNewBlobFile("text/plain");
	
		  // Open a channel to write to it
		  boolean lock = false;
		  FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
	
		  // Different standard Java ways of writing to the channel
		  // are possible. Here we use a PrintWriter:
		  PrintWriter out = new PrintWriter(Channels.newWriter(writeChannel, "UTF8"));
		  out.println("The woods are lovely dark and deep.");
		  out.println("But I have promises to keep.");
	
		  // Close without finalizing and save the file path for writing later
		  out.close();
		  String path = file.getFullPath();
	
		  // Write more to the file in a separate request:
		  file = new AppEngineFile(path);
	
		  // This time lock because we intend to finalize
		  lock = true;
		  writeChannel = fileService.openWriteChannel(file, lock);
	
		  // This time we write to the channel directly
		  writeChannel.write(ByteBuffer.wrap
		            ("And miles to go before I sleep.".getBytes()));
	
		  // Now finalize
		  writeChannel.closeFinally();
	
		  // Later, read from the file using the file API
		  lock = false; // Let other people read at the same time
		  FileReadChannel readChannel = fileService.openReadChannel(file, false);
	
		  // Again, different standard Java ways of reading from the channel.
		  BufferedReader reader =
		          new BufferedReader(Channels.newReader(readChannel, "UTF8"));
		       String line = reader.readLine();
		  // line = "The woods are lovely dark and deep."
	
		  readChannel.close();
	
		  // Now read from the file using the Blobstore API
		  BlobKey blobKey = fileService.getBlobKey(file);
		  BlobstoreService blobStoreService = BlobstoreServiceFactory.getBlobstoreService();
		  String segment = new String(blobStoreService.fetchData(blobKey, 30, 40));	  
	  }		*/
}
